import struct

# Chunk types
UNDEFINED = -1
DATA_CHUNK = 0
END_CHUNK = 1


# Data structure: (type, length of id, seq#) + id
class Chunk:
    
    def __init__(self, mid, seq):
        self.mid = mid
        self.seq = seq
        self.type = -1

    def raw(self):
        return struct.pack('iii', self.type, self.mid, self.seq) 

    @staticmethod
    def from_raw(raw):
        ctype, = struct.unpack('i', raw[:4])
        return types[ctype].from_raw(raw)
        
class DataChunk(Chunk):
    
    def __init__(self, mid, seq, data):
        Chunk.__init__(self, mid, seq)
        self.data = data
        self.type = 0

    def raw(self):
        return Chunk.raw(self) + self.data 

    @staticmethod
    def from_raw(raw):
        ctype, mid, seq = struct.unpack('iii', raw[:12])
        data = raw[12:]
        return DataChunk(mid, seq, data)

class EndChunk(Chunk):
    
    def __init__(self, mid, seq):
        Chunk.__init__(self, mid, seq)
        self.type = 1

    def raw(self):
        return Chunk.raw(self)

    @staticmethod
    def from_raw(raw):
        ctype, mid, seq = struct.unpack('iii', raw[:12])
        return EndChunk(mid, seq)
        
        
        
types = {
    -1: Chunk,
    0: DataChunk,
    1: EndChunk,
}
